package com.example.filter;

import com.alibaba.fastjson.JSON;
import com.example.domain.vo.LoginUser;
import com.example.exception.CustomerAuthenticationException;
import com.example.handler.LoginFailureHandler;
import com.example.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;

//每一个servlet请求，只会执行一次
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    @Autowired
    private LoginFailureHandler loginFailureHandler;
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        //1.判断如果是访问登录接口/user/login直接放行
        try {
            String uri = request.getRequestURI();
            System.out.println(uri);

            if (!uri.equals("/user/login")) {
                this.validateToken(request);
                return;
            }
        } catch (AuthenticationException e) {
          loginFailureHandler.onAuthenticationFailure(request,response,e);
        }
        //5.放行
        filterChain.doFilter(request,response);
    }

        //用于token的校验，只在过滤器中用
        private void validateToken(HttpServletRequest request){
            //1.登陆了再次请求其它认证资源
            String uri = request.getRequestURI();
            System.out.println("进入校验："+uri);

            //2.判断token令牌是否为空
            String token = request.getHeader("Authorization");
            if (ObjectUtils.isEmpty(token)){
                token = request.getParameter("Authorization");
            }
            if (ObjectUtils.isEmpty(token)) {
                throw new CustomerAuthenticationException("token为空");
            }
            //3.校验令牌成功还是失败
            LoginUser loginUser;
            try {
                Claims claims = JwtUtil.parseJWT(token);
                String loginUserString = claims.getSubject();
                //把字符串转成loginUser对象
                loginUser = JSON.parseObject(loginUserString, LoginUser.class);
            } catch (Exception e) {
                throw new CustomerAuthenticationException("token校验失败");
            }
            //4.把验证完获取到的用户信息再次放入springsecurity的上下文
            UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(loginUser, null, loginUser.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(authentication);

        }


}
